Skip to content

feat: Error sanitization for user-facing services #413

Merged
gokutheengineer merged 4 commits intobsv-blockchain:mainfrom
gokutheengineer:gokhan/concat-error-msgs
Feb 19, 2026
Merged

feat: Error sanitization for user-facing services #413
gokutheengineer merged 4 commits intobsv-blockchain:mainfrom
gokutheengineer:gokhan/concat-error-msgs

Conversation

@gokutheengineer
Copy link
Copy Markdown
Collaborator

@gokutheengineer gokutheengineer commented Jan 19, 2026

Error Sanitization for User-Facing Services

Context

We observed verbose error chains leaking internal details (e.g., Aerospike, underlying storage errors, and deep wrapped chains) into user-facing surfaces (propagation, asset server, p2p). This is useful for debugging but not appropriate for external clients.

Goal

Return succinct, safe error messages to users while preserving full error detail in logs and internal chains.

Summary of Changes

  1. Centralized sanitization helpers

    • Added helpers in errors to generate concise, public-safe messages and sanitized errors for gRPC/HTTP.
  2. Propagation service sanitization

    • HTTP endpoints now return short messages (no wrapped chain or data).
    • gRPC errors are wrapped with sanitized status (code + message only).
    • Batch responses return sanitized TError per item.
  3. Asset server sanitization

    • HTTP error responses now use sanitized messages.
  4. P2P API sanitization

    • User-facing gRPC endpoints return sanitized errors instead of raw internal chains.

Detailed Changes

New error helpers (errors/errors.go)

  • UserMessage(err)
    Returns a concise message like TX_INVALID (31): tx invalid (no wrapped chain, no data).
  • PublicError(err)
    Creates a sanitized *errors.Error with only code + message.
  • WrapGRPCPublic(err)
    Produces a gRPC status with only the sanitized code/message.
  • WrapPublic(err)
    Converts to sanitized *errors.TError (used in batch responses).

Propagation (services/propagation/Server.go)

  • /tx and /txs HTTP error responses now use errors.UserMessage(err)
    (removes internal storage/db details and long chains).
  • gRPC ProcessTransaction returns WrapGRPCPublic(err) to keep responses minimal.
  • Batch ProcessTransactionBatch uses WrapPublic(err) per item to strip details.

Asset server (services/asset/httpimpl/sendError.go)

  • JSON error response now uses errors.UserMessage(err) instead of err.Error().

P2P (services/p2p/Server.go)

  • Sanitized errors for user-facing endpoints:
    • GetPeers when P2P client not initialized
    • BanPeer, UnbanPeer errors
    • RecordBytesDownloaded decode errors

Example Before/After

Before (too verbose):

PROCESSING (4): [Validate][txid] error spending utxos -> PROCESSING (4): validator: UTXO Store spend failed ... -> TX_INVALID (31): error in aerospike spend ... -> 70: UTXO_SPENT (70): ... "utxo ... already spent by ..."

After (sanitized):

TX_INVALID (31): tx invalid

or

UTXO_SPENT (70): utxo already spent

Files Touched

  • errors/errors.go
  • services/propagation/Server.go
  • services/asset/httpimpl/sendError.go
  • services/p2p/Server.go

Risks / Considerations

  • Less detail for external users; internal logs still preserve full chains.
  • gRPC clients now receive sanitized errors, so any client-side logic depending on deep error chains should be reviewed.

Follow-ups (Optional)

  • Extend sanitization to other external surfaces (RPC/validator/legacy APIs).
  • Add a config flag to toggle verbose vs public errors for debug environments.
  • Add tests verifying sanitized responses.

Note

There is an additional change in services/propagation/Server.go to ignore ErrBlobAlreadyExists when storing transactions. This appears separate from sanitization and is not part of the error-sanitization scope.

@gokutheengineer gokutheengineer changed the title feat: concat error messages for user facing errors feat: clenaup error messages for user facing errors Jan 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 19, 2026

🤖 Claude Code Review

Status: Complete


Summary:
This PR successfully implements error sanitization for user-facing services (propagation, asset server, p2p). The implementation properly strips internal details (wrapped errors, file paths, stack traces, error data) from external responses while preserving full error context in logs.

Key Changes:

  • Added 4 sanitization functions in errors/errors.go: UserMessage(), PublicError(), WrapGRPCPublic(), WrapPublic()
  • Applied sanitization across HTTP and gRPC endpoints in propagation, asset server, and p2p services
  • Comprehensive test coverage (436 lines) including security scenarios

Review Result: ✅ No issues found

The code is well-implemented with:

  • Proper security boundaries between internal and external errors
  • Correct concurrency patterns (WaitGroup provides happens-before guarantees)
  • Thorough test coverage including edge cases and security scenarios
  • Consistent application across all user-facing surfaces

Note: The PR description mentions an ErrBlobAlreadyExists change, but that is correctly noted as out-of-scope and not included in this PR.

@gokutheengineer gokutheengineer changed the title feat: clenaup error messages for user facing errors feat: Error sanitization for user-facing services Jan 19, 2026
@gokutheengineer gokutheengineer requested review from icellan and removed request for icellan January 27, 2026 08:47
@gokutheengineer gokutheengineer force-pushed the gokhan/concat-error-msgs branch from 9b0916e to 0f870c1 Compare January 27, 2026 13:30
@gokutheengineer gokutheengineer force-pushed the gokhan/concat-error-msgs branch from 49ac4fe to bccdcaa Compare February 19, 2026 11:47
@sonarqubecloud
Copy link
Copy Markdown

@gokutheengineer gokutheengineer merged commit 026f945 into bsv-blockchain:main Feb 19, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants